iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0

上回簡單說了如何使用,這次就要開始實操
在真正的設計前,需要先考量需要的功能與資料,但大部分還是邊寫邊加

資料內容

在這個專案中,我們需要一個todoList,被選取的todo和是否是update的輸入
其中需要的延伸功能有Group的list等

data class TodoItem(  
    var title: String = "",  
    var content: String = "",  
    var group: String = "",  
    var done: Boolean = false  
)  
  
class GlobalVM : ViewModel() {  
    private val _todoList = MutableStateFlow<List<TodoItem>>(emptyList())  
    val todoList: StateFlow<List<TodoItem>> = _todoList  
  
    private val _isUpdate = MutableStateFlow<Boolean>(false)  
  
    private val _currentTodo = MutableStateFlow<TodoItem>(TodoItem())  
    val currentTodo: StateFlow<TodoItem> = _currentTodo  
  
    // TodoList  
    fun submitTodo(todoItem: TodoItem) {}  
    
    fun checkedTodo(todoItem: TodoItem, checked: Boolean) {}
  
    // Check update  
    fun resetUpdate() {}  
  
    // CurrentTodo  
    fun focusTodo(todoItem: TodoItem) {}  
    
    // Current Group  
	fun focusGroup(groupName: String) {}
}

這邊沒有將_isUpdate設成public,因為我認為他是屬於邏輯層處理的一個flag,其中

  • resetUpdate() 主要是保護機制,避免畫面切換後還殘留「更新狀態」
  • focusTodo() 是進入編輯模式,UI 層可以依照 _isUpdate 的值來決定要顯示「新增」還是「更新」的按鈕

由於這個應用十分的簡單,所以並不用兩個viewmodel,也沒有很多的邏輯

資料邏輯

既然大概知道需要甚麼資料與功能,就可以著手設計邏輯部分
這邊沒有設計刪除的功能是因為這邊還停留在展示階段,具體的CRUD會由資料庫完成

提交

首先就是提交todo,我考慮了這是更新還是單純的新增,以及按下checkedbox的情況

fun submitTodo(todoItem: TodoItem) {  
    if (_isUpdate.value){  
        _todoList.update { list ->
            list.map { if (it == _currentTodo.value) todoItem else it }
        }  
        _isUpdate.update { false }  
    }  
    else  
        _todoList.update { it + todoItem }  
}

fun checkedTodo(todoItem: TodoItem, checked: Boolean) {  
    _todoList.update { list ->  
        list.map { if (it == todoItem) todoItem.copy(done = checked) else it }  
    }
}

取消更新狀態

我想在todo的地方可以按更新,這樣他就可以進入更新狀態,但如果畫面切掉就不會進這個狀態

fun resetUpdate() {  
    _isUpdate.update { false }  
    _currentTodo.update { TodoItem() }  
}

開始更新

在todo被按下更改的時候就會觸發,並把使用者跳轉到輸入畫面

fun focusTodo(todoItem: TodoItem) {  
    _isUpdate.update { true }  
    _currentTodo.update { todoItem }  
}

選取Group

// Current Group  
fun focusGroup(groupName: String) {  
    _currentGroup.update { groupName }  
}

這樣就設計完了非常基礎的viewmodel
下一步就是把這些狀態接到 Composable 上,讓我們能做到:

  • 新增 Todo
  • 點擊 Todo 進入編輯
  • 修改後儲存回去
    這樣 Todo App 才算是「真的能用」

上一篇
Day 16:甚麼是ViewModel,如何分離UI與邏輯資料
下一篇
Day 18:將ViewModel與UI結合
系列文
現代Android jetpack compose開發入門21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言